package org.yaac.server.conf;

import javax.inject.Singleton;

import org.yaac.client.service.BlobService;
import org.yaac.client.service.CRUDService;
import org.yaac.client.service.ChannelClientService;
import org.yaac.client.service.EGQLService;
import org.yaac.client.service.OverviewService;
import org.yaac.client.service.StatisticsService;
import org.yaac.server.delegate.AsyncMemcacheServiceDelegate;
import org.yaac.server.delegate.AsyncMemcacheServiceDelegateImpl;
import org.yaac.server.delegate.MemcacheServiceDelegate;
import org.yaac.server.delegate.MemcacheServiceDelegateImpl;
import org.yaac.server.delegate.UserServiceDelegate;
import org.yaac.server.delegate.UserServiceDelegateImpl;
import org.yaac.server.file.BlobUploadServlet;
import org.yaac.server.file.FileDownloadServlet;
import org.yaac.server.file.CacheUploadServlet;
import org.yaac.server.service.BlobServiceImpl;
import org.yaac.server.service.CRUDServiceImpl;
import org.yaac.server.service.ChannelClientServiceImpl;
import org.yaac.server.service.EGQLServiceImpl;
import org.yaac.server.service.OverviewServiceImpl;
import org.yaac.server.service.StatisticsServiceImpl;

import com.google.appengine.tools.pipeline.PipelineService;
import com.google.appengine.tools.pipeline.impl.servlets.PipelineServlet;
import com.google.inject.servlet.ServletModule;

/**
 * @author Max Zhu (thebbsky@gmail.com)
 *
 */
public class YaacModule extends ServletModule {

	@Override
	protected void configureServlets() {
		// url mapping
		serve("/yaac/GWT.rpc").with(GWTRPCFacadeServlet.class);	// GWT facade handles GWT requests
		serve("/download").with(FileDownloadServlet.class);		// File download requests
		serve("/upload/cache").with(CacheUploadServlet.class);			// File upload to memcache
		serve("/upload/blob").with(BlobUploadServlet.class);			// File upload to blob
		serve("/_ah/pipeline/*").with(PipelineServlet.class);	// Pipeline requests
		filter("/*").through(GWTCacheControlFilter.class);		// make sure browser will not cache nocache.js
		
		// servlets
		bind(GWTRPCFacadeServlet.class).in(Singleton.class);	// Facade servlet to handle all GWT RPC requests
		bind(GWTCacheControlFilter.class).in(Singleton.class);	// cache control
		bind(FileDownloadServlet.class).in(Singleton.class);	// file download servlet (blobstore / datastore blob and text)
		bind(CacheUploadServlet.class).in(Singleton.class);		// file upload servlet (tmp file for blobstore / datastore blob and text)
		bind(BlobUploadServlet.class).in(Singleton.class);		// file upload servlet (tmp file for blobstore / datastore blob and text)
		bind(PipelineServlet.class).in(Singleton.class);		// pipeline servlet
		
		// remote services
		bind(OverviewService.class).to(OverviewServiceImpl.class).in(Singleton.class);
//		bind(StatisticsService.class).to(org.yaac.server.stat.MockStatisticsService.class).in(Singleton.class);
		bind(StatisticsService.class).to(StatisticsServiceImpl.class).in(Singleton.class);
		bind(CRUDService.class).to(CRUDServiceImpl.class).in(Singleton.class);
		bind(EGQLService.class).to(EGQLServiceImpl.class).in(Singleton.class);
		bind(BlobService.class).to(BlobServiceImpl.class).in(Singleton.class);
		bind(ChannelClientService.class).to(ChannelClientServiceImpl.class).in(Singleton.class);
		
		// delegates
		bind(UserServiceDelegate.class).to(UserServiceDelegateImpl.class).in(Singleton.class);
		bind(MemcacheServiceDelegate.class).to(MemcacheServiceDelegateImpl.class).in(Singleton.class);
		bind(AsyncMemcacheServiceDelegate.class).to(AsyncMemcacheServiceDelegateImpl.class).in(Singleton.class);
		
		// third party services
		bind(PipelineService.class).toProvider(PipelineServiceProvider.class).in(Singleton.class);
	}
}
